///////////////////////////////////////////////////////////////////////////
//																		 //
//	Author:		Michael Mozdzierz										 //
//	Date:		10/25/2014												 //
//	Purpose:	Manages and update particles							 //
//																		 //
///////////////////////////////////////////////////////////////////////////

#ifndef _PARTICLE_EMITTER_H
#define _PARTICLE_EMITTER_H

#include "Particle.h"
#include <vector>
#include "..\..\EdgeMath\Vectors.h"
#include "..\..\EdgeMath\Geometry.h"
#include "..\..\EdgeGraphics\ConstantBuffer.h"
#include "..\..\EdgeMath\VectorHelper.h"

#define MAX_PARTICLES 1000

using namespace std;

struct Particle;
struct Material;
class ParticleSystem;

class ParticleEmitter
{
	friend class Chunk;
	friend class ContentManager;
	friend class ParticleSystem;

	// sructure for geometry shader const buffer
	struct VRAM
	{
		Matrix world;
		Matrix view;
		Matrix proj;

		Vector4 color;

		float scale = 1.f;
		float alpha = 1.f;

		float padding[2];
	} toShader;

	ConstantBuffer<VRAM>* gShaderConstBuffer = nullptr;

	// parent system of this particle emitter
	ParticleSystem* parent;

	// all the particles being managed by this emitter
	Particle particles[MAX_PARTICLES];

	// the area that this emitter spawns particles in
	Box3D region;

	// starting color
	Vector4 max_startColor = VectorHelper::vector_4::white;
	Vector4 min_startColor = VectorHelper::vector_4::white;

	// ending color
	Vector4 max_endColor;
	Vector4 min_endColor;

	// slowest a particle will move
	Vector3 min_velocity;
	// fastest a particle will move
	Vector3 max_velocity;

	// upper and lower bounds for randomized  accelartion
	Vector3 min_acceleration;
	Vector3 max_acceleration;

	// upper and lower bounds for randomized starting rotation
	float min_rotation = 0.f;
	float max_rotation = 0.f;

	// upper and lower bounds for randomized rotation speed
	float min_rotationSpeed = 0.f;
	float max_rotationSpeed = 0.f;

	// upper and lower bounds for randomized start alpha
	float min_startAlpha = 1.f;
	float max_startAlpha = 1.f;

	// upper and lower bounds for randomized end alpha
	float min_endAlpha = 1.f;
	float max_endAlpha = 1.f;

	// upper and lower bounds for randomized start size
	float min_startSize = 1.f;
	float max_startSize = 1.f;

	// upper and lower bounds for randomized end size
	float min_endSize = 1.f;
	float max_endSize = 1.f;

	// upper and lower bounds for randomized life time
	float min_lifetime;
	float max_lifetime;

	// how often the system calles emit. the emitter will 
	// not call emit on its own if emit_frequency is set to the default, 0
	float emit_frequency = 0.f;
	// the ammount of time remaining untill the next call to emit
	float emit_timer = 0.f;
	// the ammount of particles to emit, if emitting on a frequency
	unsigned int emit_burst = 0;

	// texture for all particles
	Material* texture;

public:
	ParticleEmitter(void);
	~ParticleEmitter(void);

	void Emit(unsigned int numParticles);

	void Update(float dt);
	void Draw(void);
};

#endif